﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.ComponentModel;
using Eudaemon.ProeAssist.WinGUIControls.Properties;
using System.Drawing;
using System.Windows.Forms;
using System.Drawing.Drawing2D;

namespace Eudaemon.ProeAssist.WinGUIControls
{
    /// <summary>
    /// 1. sort a column (generally by click the column header)
    ///       (1) display up/down sort arrow indicators 
    /// 2. add more controls like tree/pictures
    /// </summary>
    public class FileListView : System.Windows.Forms.ListView, ISupportInitialize
    {
        public FileListView()
        {
            _columnSorter = new ListViewColumnSorter();
            this.ListViewItemSorter = _columnSorter;
            this.ColumnClick += new ColumnClickEventHandler(FileListView_ColumnClick);
            //this.OwnerDraw = true;
            //this.DrawColumnHeader += new DrawListViewColumnHeaderEventHandler(FileListView_DrawColumnHeader);
            //this.DrawItem += new DrawListViewItemEventHandler(FileListView_DrawItem);
            //this.DrawSubItem += new DrawListViewSubItemEventHandler(FileListView_DrawSubItem);
        }

        //void FileListView_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
        //{
        //    TextFormatFlags flags = TextFormatFlags.Left;
        //    //e.Graphics.FillRectangle(Brushes.Tomato, e.Bounds);

        //    using (StringFormat sf = new StringFormat())
        //    {
        //        // Store the column text alignment, letting it default
        //        // to Left if it has not been set to Center or Right.
        //        switch (e.Header.TextAlign)
        //        {
        //            case HorizontalAlignment.Center:
        //                sf.Alignment = StringAlignment.Center;
        //                flags = TextFormatFlags.HorizontalCenter;
        //                break;
        //            case HorizontalAlignment.Right:
        //                sf.Alignment = StringAlignment.Far;
        //                flags = TextFormatFlags.Right;
        //                break;
        //        }
        //        e.DrawText(flags);
        //    }
        //}

        //void FileListView_DrawItem(object sender, DrawListViewItemEventArgs e)
        //{
        //    if ((e.State & ListViewItemStates.Selected) != 0)
        //    {
        //        // Draw the background and focus rectangle for a selected item.
        //        e.Graphics.FillRectangle(Brushes.GreenYellow, e.Bounds);
        //        e.DrawFocusRectangle();
        //    }
        //    else
        //    {
        //        // Draw the background for an unselected item.
        //        e.Graphics.FillRectangle(Brushes.White, e.Bounds);
        //    }
        //    // Draw the item text for views other than the Details view.
        //    if (this.View != View.Details)
        //    {
        //        e.DrawText();
        //    }
        //}

        //void FileListView_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
        //{
        //    using (StringFormat sf = new StringFormat())
        //    {
        //        // Store the column text alignment, letting it default
        //        // to Left if it has not been set to Center or Right.
        //        switch (e.Header.TextAlign)
        //        {
        //            case HorizontalAlignment.Center:
        //                sf.Alignment = StringAlignment.Center;
        //                break;
        //            case HorizontalAlignment.Right:
        //                sf.Alignment = StringAlignment.Far;
        //                break;
        //        }
        //        // Draw the standard header background.
        //        e.DrawBackground();
        //        // Draw the header text.
        //        e.Graphics.DrawString(e.Header.Text, this.Font,
        //            Brushes.Black, e.Bounds, sf);
        //    }
        //}

        void FileListView_ColumnClick(object sender, ColumnClickEventArgs e)
        {
            // Determine if clicked column is already the column that is being sorted.
            if (e.Column == _columnSorter.SortColumn)
            {
                // Reverse the current sort direction for this column.
                if (_columnSorter.Order == SortOrder.Ascending)
                    _columnSorter.Order = SortOrder.Descending;
                else
                    _columnSorter.Order = SortOrder.Ascending;
            }
            else
            {
                // Set the column number that is to be sorted; default to ascending.
                _columnSorter.SortColumn = e.Column;
                _columnSorter.Order = SortOrder.Ascending;
            }
            // Perform the sort with these new sort options.
            this.Sort();
        }

        #region ISupportInitialize Members

        public void BeginInit()
        {
            InitAppearance();
            InitColumns();
        }

        public void EndInit()
        {
        }

        #endregion

        private void InitAppearance()
        {
            this.View = View.Details;
            this.BorderStyle = BorderStyle.None;
            this.FullRowSelect = true;
            this.GridLines = false;
        }

        private void InitColumns()
        {
            int index = 0;
            this.Columns.Add(new ColumnHeader());
            this.Columns[index].Name = this.Columns[index].Text = "Name";
            this.Columns[index].Width = (int)(this.Width * 0.3);
            ++index;
            this.Columns.Add(new ColumnHeader());
            this.Columns[index].Name = this.Columns[index].Text = "Type";
            this.Columns[index].Width = (int)(this.Width * 0.2);
            ++index;
            this.Columns.Add(new ColumnHeader());
            this.Columns[index].Name = this.Columns[index].Text = "Version";
            this.Columns[index].Width = (int)(this.Width * 0.1);
            ++index;
            this.Columns.Add(new ColumnHeader());
            this.Columns[index].Name = this.Columns[index].Text = "Size(KB)";
            this.Columns[index].Width = (int)(this.Width * 0.1);
            ++index;
            this.Columns.Add(new ColumnHeader());
            this.Columns[index].Name = this.Columns[index].Text = "Last Accessed";
            this.Columns[index].Width = (int)(this.Width * 0.15);
            ++index;
            this.Columns.Add(new ColumnHeader());
            this.Columns[index].Name = this.Columns[index].Text = "Creation";
            this.Columns[index].Width = (int)(this.Width * 0.15);
        }       

        private ListViewColumnSorter _columnSorter;
    }

    /// <summary>
    /// Reference: "How to sort a ListView control by a column in Visual C#"
    /// </summary>
    public class ListViewColumnSorter : IComparer
    {
        public ListViewColumnSorter()
        {
            _columnToSort = 0;
            _orderOfSort = SortOrder.None;
            _objectCompare = new CaseInsensitiveComparer();
        }

        #region IComparer Members

        /// <summary>
        /// Compares the two objects passed using a case insensitive comparison.
        /// </summary>
        /// <param name="x">First object to be compared</param>
        /// <param name="y">Second object to be compared</param>
        /// <returns>The result of the comparison. "0" if equal, negative if 'x' is less than 'y' and positive if 'x' is greater than 'y'</returns>
        public int Compare(object x, object y)
        {
            int compareResult;
            ListViewItem listviewX, listviewY;
            listviewX = (ListViewItem)x;
            listviewY = (ListViewItem)y;

            // if one object has a null column(subitem), simply take them as equal.
            if (_columnToSort >= listviewX.SubItems.Count || _columnToSort >= listviewY.SubItems.Count)
            {
                return 0;
            }
          
            compareResult = _objectCompare.Compare(listviewX.SubItems[_columnToSort].Text, 
                listviewY.SubItems[_columnToSort].Text);
            // Calculate correct return value based on object comparison
            if (_orderOfSort == SortOrder.Ascending)
            {
                return compareResult;
            }
            else if (_orderOfSort == SortOrder.Descending)
            {
                return (-compareResult);
            }
            else
            {
                return 0;
            }
        }

        #endregion

        /// <summary>
        /// Gets or sets the number of the column to which to apply the sorting operation (Defaults to '0').
        /// </summary>
        public int SortColumn
        {
            set
            {
                _columnToSort = value;
            }
            get
            {
                return _columnToSort;
            }
        }

        /// <summary>
        /// Gets or sets the order of sorting to apply (for example, 'Ascending' or 'Descending').
        /// </summary>
        public SortOrder Order
        {
            set
            {
                _orderOfSort = value;
            }
            get
            {
                return _orderOfSort;
            }
        }

        private int _columnToSort;
        private SortOrder _orderOfSort;
        private CaseInsensitiveComparer _objectCompare;
    }
}
